package com.ms.game.itembox;

import java.util.ArrayList;
import java.util.Date;

import org.hibernate.Session;

import com.ms.game.itembox.container.ItemBasic;
import com.ms.game.itembox.db.AccountItemChangeLogModel;
import com.ms.game.itembox.db.AccountItemModel;
import com.ms.game.itembox.db.ItemDAO;
import com.ms.player.Player;
import com.ms.player.PlayerUserType;
import com.ms.service.error.ErrorCode;
import com.ms.service.module.account.Account;
import com.ms.service.module.account.db.AccountDAO;
import com.ms.service.module.zone.command.BasicDebugCommand;
import com.ms.service.module.zone.command.CommandHelper;
import com.ms.service.module.zone.module.BasicZoneModule;
import com.xpec.c4.db.hibernate.manager.HibernateLogManager;
import com.xpec.c4.db.hibernate.manager.HibernateManager;
import com.xpec.c4.game.datamanager.BaseDataInfo;
import com.xpec.c4.game.time.TimeConstants;
import com.xpec.c4.game.time.TimeSys;
import com.xpec.c4.game.utility.GUID;
import com.xpec.c4.game.utility.GUIDFactory;
import com.xpec.c4.game.utility.GUIDType;
import com.xpec.c4.game.utility.GameUtility;
import com.xpec.c4.message.ConstantCode;
import com.xpec.c4.message.MessageTypes;
import com.xpec.c4.service.message.MessageAction;
import com.xpec.c4.service.module.common.ItemInfoManager;
import com.xpec.c4.service.module.common.PlayerCommonInfoManager;

/**
 * 測試拉彩公告
 * 
 * @author kvn_yang
 */
public class ItemCommand extends BasicDebugCommand {

	/** 列出道具清單 */
	static final private int PARAM_LIST = 1;

	/** 使用 */
	static final private int PARAM_USE = 2;
	static final private int USE_INDEX_ITEM_INDEX = 2;
	static final private int USE_INDEX_TARGET_NAME = 3;

	/** 增加 */
	static final private int PARAM_ADD = 3;
	static final private int ADD_TYPE = 2;
	static final private int ADD_INDEX_ITEMID = 3;
	static final private int ADD_INDEX_COUNT = 4;

	/** 減少 */
	static final private int PARAM_SUB = 4;
	static final private int SUB_INDEX_ITEM_INDEX = 2;
	static final private int SUB_INDEX_COUNT = 3;

	/** 精煉 */
	static final private int PARAM_REFINE = 5;
	static final private int REFINE_INDEX_ITEM_INDEX = 2;
	
	/** 刪除所有道具*/
	private static final int PARAM_SUB_ALL = 6;
	private static final int PARAM_SUB_TYPE = 2;
	private static final int PARAM_BASIC_ITEM_ID = 3;

	private CommandHelper helper = new CommandHelper(getName());

	public ItemCommand() {
		helper.addParam(PARAM_LIST, "list", "");
		helper.addParam(PARAM_USE, "use", "[item index] [target name]");
		helper.addParam(PARAM_ADD, "add", "[type 0: account | 1: player] [item id] [count]");
		helper.addParam(PARAM_SUB, "sub", "[item index] [count]");
		helper.addParam(PARAM_REFINE, "refine", "[item index]");
		helper.addParam(PARAM_SUB_ALL, "subAll", "[type 0: account | 1: player] [basic item Id]");
		
	}

	@Override
	public String execute() {
		int index = helper.getCommandIndex(commandValue);

		BasicZoneModule module = getModule();
		if (module == null) {
			return "can't get current module.";
		}

		Player player = getPlayer();
		if (player == null) {
			return "can't get current player.";
		}

		// order id
		GUID orderId = GUIDFactory.createUUID(GUIDType.TYPE_COMMAND_ORDER_ID);

		// game hall info
		String gameHallId = module.getModuleName();
		String gameHallName = "";

		ChangeItemLister itemLister = new ChangeItemLister();
		ItemChangeWay changeWay = null;
		switch (index) {
		case PARAM_LIST: // 列出所有道具
			return player.getItemBox().toString();

		case PARAM_USE: { // 使用道具
			// 道具序號
			String itemIndex = getParam(USE_INDEX_ITEM_INDEX);
			if (itemIndex == null) {
				return getDescription();
			}

			String itemSn = null;
			if (GameUtility.isNumeric(itemIndex)) {
				int itemIndexValue = Integer.valueOf(itemIndex);
				int i = 0;
				for (Item item : player.getItemBox().getItems()) {
					if (i == itemIndexValue) {
 						itemSn = item.getSn();
						break;
					}
					i++;
				}
			}
			if (itemSn == null) {
				return getDescription();
			}

			// 目標 name
			String targetName = getParam(USE_INDEX_TARGET_NAME);

			changeWay = ItemChangeWay.SUB_COMMAND;

			int res = player.getItemBox().useItem(getModule(), player.getZoneId(), "", player, itemSn, 1,
					targetName);

			// 取得結果字串
			String resString = ConstantCode.getName(ErrorCode.class, res);

			return resString;
		}

		case PARAM_ADD: { // 取得道具
			int type = 0;
			if (GameUtility.isNumeric(getParam(ADD_TYPE))) {
				type = Integer.valueOf(getParam(ADD_TYPE));
				if (type > 1 || type < 0) {
					return getDescription();
				}
			} else {
				return getDescription();
			}
			
			if (type == 0) {
				String itemId = getParam(ADD_INDEX_ITEMID);
				if (!GameUtility.isHaveString(itemId)) {
					return getDescription();
				}
				
				// 確認物品資料
				ItemBasic item = ItemInfoManager.getInstance().getItem(itemId);
				if (item == null) {
					return "item [" + itemId + "] not exist in bin.";
				}
				
				// 變更數量
				int count = 0;
				if (GameUtility.isNumeric(getParam(ADD_INDEX_COUNT))) {
					count = Integer.valueOf(getParam(ADD_INDEX_COUNT));
					if (count <= 0) {
						return getDescription();
					}
				} else {
					return getDescription();
				}
				
				ArrayList<AccountItemChangeLogModel> logList = new ArrayList<AccountItemChangeLogModel>();

				Session session = HibernateManager.txBegin();
				for (int i = 0 ; i < count ; i ++) {
					AccountItemModel model = new AccountItemModel();
					model.setItemId(item.getItemId());
					model.setCount(1);
					model.setSn(GUIDFactory.createUUID(GUIDType.TYPE_ACCOUNT_ITEM).toString());
					model.setOwnerAccountId(player.getAccountId().toString());
					model.setStatus(ItemStatus.NORMAL.getId());
					model.setStatusDesc(ItemStatus.NORMAL);
					model.setHasExpireTime(item.isHasExpireTime());
					
					long expireTime = 0;
					if (item.isHasExpireTime()) {
						expireTime =  TimeSys.currentTimeMills() + (item.getExpireTime() * TimeConstants.MILLI_SECOND_PRE_HOUR);
						Date date = new Date(expireTime);
						date = GameUtility.getDateOnly(date);
						expireTime = date.getTime() / 1000;
					}
									
					model.setExpireTime(expireTime);
					session.save(model);
					session.flush();
					
					AccountItemChangeLogModel itemChangeLogModel = ItemDAO.makeAccountItemChangeLogModel(orderId.toString(), player.getAccountId().toString(), 
							null, null, PlayerUserType.PLAYER, model.getSn(), item.getItemId(), 
							item.getName(), 1, 0, 1, AccountItemChangeWay.ADD_COMMAND, null, null ,null , null, null);
					logList.add(itemChangeLogModel);
				}
				HibernateManager.txCommitFailRollbackClearSession();
				session = HibernateLogManager.txBegin();
				for (AccountItemChangeLogModel accountItemChangeLogModel : logList) {
					session.save(accountItemChangeLogModel);
				}
				HibernateLogManager.txCommitFailRollbackClearSession();

				Account account = AccountDAO.loadAccountByAccountId(player.getAccountId());
				for (GUID guid : account.getPlayers()) {
					GUID sessionId = PlayerCommonInfoManager.getInstance().getSessionByPlayerGuid(guid);
					if(sessionId == null){
						continue;
					}
					MessageAction.sendMessage(sessionId, MessageTypes.S_ZONE_CAN_ASK_ACCOUNT_ITEM_LIST, "");
				}
				return "ok";
			} else if (type == 1) {
				
				// 道具 id
				String itemId = getParam(ADD_INDEX_ITEMID);
				if (!GameUtility.isHaveString(itemId)) {
					return getDescription();
				}

				// 確認物品資料
				ItemBasic item = ItemInfoManager.getInstance().getItem(itemId);
				if (item == null) {
					return "item [" + itemId + "] not exist in bin.";
				}

				// 變動原因
				changeWay = ItemChangeWay.ADD_COMMAND;

				// 變更數量
				int count = 0;
				if (GameUtility.isNumeric(getParam(ADD_INDEX_COUNT))) {
					count = Integer.valueOf(getParam(ADD_INDEX_COUNT));
					if (count <= 0) {
						return getDescription();
					}
				} else {
					return getDescription();
				}

				itemLister.addItem(null, itemId, count, item.getItemRefineLevel());
				break;
			} else {
				return getDescription();
			}
		}

		case PARAM_SUB: { // 減少道具
			// 道具序號
			String itemIndex = getParam(SUB_INDEX_ITEM_INDEX);
			if (itemIndex == null) {
				return getDescription();
			}

			String itemSn = null;
			int refineLevel = 0;
			int count = 0;
			if (GameUtility.isNumeric(getParam(SUB_INDEX_COUNT))) {
				count = Integer.valueOf(getParam(SUB_INDEX_COUNT));
				if (count <= 0) {
					return getDescription();
				}
			} else {
				return getDescription();
			}
			

			for (Item item : player.getItemBox().getItems()) {
				if (item.getItemId().equals(itemIndex)) {
					if (item.getCount() >= count) {
						itemSn = item.getSn();
						refineLevel= item.getRefineLevel();
						break;
					}
				}
			}
			
			if (itemSn == null) {
				return "index invalid.";
			}

			// 變動原因
			changeWay = ItemChangeWay.SUB_COMMAND;

			// 變更數量
			itemLister.addItem(itemSn, null, count, refineLevel);
			break;
		}

		case PARAM_REFINE: { // 精煉道具
			// 道具序號
			String itemIndex = getParam(REFINE_INDEX_ITEM_INDEX);
			if (itemIndex == null) {
				return getDescription();
			}

			String refineItemSn = null;
			if (GameUtility.isNumeric(itemIndex)) {
				int itemIndexValue = Integer.valueOf(itemIndex);
				int i = 0;
				for (Item item : player.getItemBox().getItems()) {
					if (i == itemIndexValue) {
						refineItemSn = item.getSn();
						break;
					}
					i++;
				}
			}
			if (refineItemSn == null) {
				return "index invalid.";
			}

			MessageAction.sendFakeClientMessage(player, player.getZoneId(), MessageTypes.C_ITEM_REFINE_REQUEST,
					refineItemSn);
			return "send to " + player.getZoneId() + " ...";
		}
		case PARAM_SUB_ALL : {
			String typeStr = getParam(PARAM_SUB_TYPE);
			if (GameUtility.isNumeric(typeStr)){
				int type = Integer.valueOf(typeStr);
				
				switch (type) {
				case 0: {
					//共用背包
					
					
					return "Not Finish Yet";
				}

				case 1: {
					//腳色背包
					
					String itemId = getParam(PARAM_BASIC_ITEM_ID);
					
					if(itemId.equals("AllItem")){
						for (Item item : player.getItemBox().getItems()) {
							itemLister.addItem(item.getSn(), null, item.getCount(), item.getRefineLevel());
						}
					}else {
						for (Item item : player.getItemBox().getItems()) {
							if(item.getBasicItemId().equals(itemId)) {
								itemLister.addItem(item.getSn(), null, item.getCount(), item.getRefineLevel());
							}
						}
					}
					
					if(itemLister.getSize() <= 0){
						return "Item Not Found";
					}
					
					changeWay = ItemChangeWay.SUB_COMMAND;					
					break;
				}

				default:
					return getDescription();
				}

			} else {
				return getDescription();
			}
			
			break;
		}
		
		default:
			return getDescription();
		}

		// 送出道具變更需求
		boolean res = module.getPlayerDataAgent().updatePlayerItemToDC(orderId, player, null, itemLister,
				changeWay, gameHallId, gameHallName, null, ItemChangeParam.NO_EXP,this, "onAddItemCommandToDcCallback");

		return (res ? "ok" : "fail");
	}

	@Override
	public String getDescription() {
		return helper.getDescription();
	}

	@Override
	public String getShortDescription() {
		return "use item, add item ....";
	}

	@Override
	public String getName() {
		return "item";
	}

	/**
	 * 金錢異動測試命令的 callback
	 * 
	 * @param obj
	 * @param userObject
	 * @see ItemCommand#execute()
	 */
	public void onAddItemCommandToDcCallback(BaseDataInfo obj, Object... userObject) {
		ItemChangeParam param = (ItemChangeParam) obj.getData();
		Player player = getPlayer();
		if (player == null) {
			return;
		}

		sendDebugCommandResponse(player.getSessionID(), param.getResultString());
	}
}
